home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2002 #11 / Amiga Plus CD - 2002 - No. 11.iso / Tools / Development / TinyGL / ami / content / ad709 / tinygl / src / glut.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-08-19  |  12.1 KB  |  436 lines

  1. /**************************************************************
  2. *
  3. * GLUT API implementation for TinyGL (AmigaDE)
  4. * (c) 2002 Ruben Monteiro
  5. *
  6. * Please see the file license.txt included in the archive for license details
  7. *
  8. ****************************************************************/
  9.  
  10. #include <stdio.h>
  11. #include <stdarg.h>
  12. #include <string.h>
  13. #include <stdlib.h>
  14. #include <lib/time.h>
  15. #include <elate/ave/ave.h>
  16. #include <ad709/tinygl/glut.h>
  17. #include <ad709/tinygl/igl.h>
  18.  
  19.  
  20. //////////// Variables and typedefs
  21.  
  22. #define LMB 1
  23. #define RMB 2
  24. #define MMB 4
  25. #define ERROR 0
  26. #define WARNING 1
  27. #define __isMouseEvent(a) a >= EV_MOUSEEVENTS && a < EV_MOUSEEVENTS+6
  28. #define __isKeyEvent(a) a >= EV_KEYBOARDEVENTS && a < EV_KEYBOARDEVENTS+3
  29. #define __getMB(a) a == 0 ? __glut_currMBDown : (a == LMB ? GLUT_LEFT_BUTTON : (a == RMB ? GLUT_RIGHT_BUTTON : GLUT_MIDDLE_BUTTON))
  30. #define __getMBState(a) a == EV_BUTTONDOWN ? GLUT_DOWN : GLUT_UP
  31. #define __getMEntry(a) a == EV_ENTER ? GLUT_ENTERED : GLUT_LEFT
  32.  
  33.  
  34. typedef struct {
  35.     ave_dev_t *ave;
  36.     ave_app_t *app;
  37.     ave_toolkit_t *tkit;
  38.     char *appname;
  39.     ave_win_t *win;
  40.     char execname[255];
  41. } glut_ave_t;
  42.  
  43.  
  44. typedef struct {
  45.     int x, y, width, height;
  46.     ave_win_t *win;
  47.     GLboolean redisplay;
  48.     GLboolean reshape;
  49.     GLboolean reposition;
  50. } glut_window_t;
  51.  
  52.  
  53.  
  54. static glut_ave_t __glut_ave;
  55. static int __glut_initX = 0, __glut_initY = 0;
  56. static int __glut_initWidth = 240, __glut_initHeight = 320;
  57. static int __glut_mouseX = 0, __glut_mouseY = 0;
  58. static int __glut_currMBDown = -1;
  59. static glut_window_t __glut_window;
  60. static IGLContext __glut_ctx = NULL;
  61. static int __glut_currWindow = 0;
  62. static int __glut_numWindows = 0;
  63. static long __glut_initTime;
  64. static GLboolean __glut_fullScreen = GL_FALSE;
  65. static GLboolean __glut_windowCreated = GL_FALSE;
  66. static char* __glut_windowName;
  67.  
  68.  
  69. typedef void (*glut_displayFunc_t) ();
  70. typedef void (*glut_reshapeFunc_t) (int width, int height);
  71.  
  72. typedef void (*glut_idleFunc_t) ();
  73. typedef void (*glut_keyboardFunc_t) (unsigned char key, int x, int y);
  74. typedef void (*glut_mouseFunc_t) (int button, int state, int x, int y);
  75. typedef void (*glut_motionFunc_t) (int x, int y);
  76. typedef void (*glut_passiveMotionFunc_t) (int x, int y);
  77. typedef void (*glut_entryFunc_t) (int state);
  78.  
  79.  
  80. static glut_displayFunc_t __glut_displayFunc = NULL;
  81. static glut_idleFunc_t __glut_idleFunc = NULL;
  82. static glut_keyboardFunc_t __glut_keyboardFunc = NULL;
  83. static glut_keyboardFunc_t __glut_keyboardUpFunc = NULL;
  84. static glut_mouseFunc_t __glut_mouseFunc = NULL;
  85. static glut_motionFunc_t __glut_motionFunc = NULL;
  86. static glut_passiveMotionFunc_t __glut_passiveMotionFunc = NULL;
  87. static glut_reshapeFunc_t __glut_reshapeFunc = NULL;
  88. static glut_entryFunc_t __glut_entryFunc = NULL;
  89. static ave_screen_info_t __glut_screen;
  90.  
  91.  
  92.  
  93. //////////// Auxiliary functions
  94.  
  95.  
  96. void __glutMessage(int type, const char *format, ...) {
  97.     va_list args;
  98.     va_start(args, format);
  99.     if (type == WARNING) {
  100.         fprintf(stderr, "GLUT: Warning in %s: ", __glut_ave.execname);
  101.     }
  102.     else {
  103.         fprintf(stderr, "GLUT: Fatal error in %s: ", __glut_ave.execname);
  104.     }
  105.     vfprintf(stderr, format, args);
  106.     va_end(args);
  107. }
  108.  
  109.  
  110. void __glutWarning(const char *format, ...) {
  111.     __glutMessage(WARNING, format);
  112. }
  113.  
  114.  
  115. void __glutError(const char *format, ...) {
  116.     __glutMessage(ERROR, format);
  117.     exit(0);
  118. }
  119.  
  120.  
  121. void __shutdownGLUT() {
  122.     glutDestroyWindow(0);
  123. }
  124.  
  125. void __setupWindow() {
  126.     if (__glut_displayFunc == NULL) {
  127.         __glutError("redisplay needed for window, but no display callback.\n");
  128.     }
  129.     if (__glut_fullScreen) {
  130.         __glut_window.width = __glut_initWidth = glutGet(GLUT_SCREEN_WIDTH);
  131.         __glut_window.height = __glut_initHeight = glutGet(GLUT_SCREEN_HEIGHT);
  132.         __glut_window.x = __glut_window.y = 0;
  133.         __glut_window.win = ave_toolkit_createdialog(__glut_ave.tkit, __glut_windowName, NULL,
  134.             __glut_window.width, __glut_window.height, FDI_CONTENT|FDI_FILLED);
  135.     }
  136.     else {
  137.         __glut_window.win = ave_toolkit_createdialog(__glut_ave.tkit, __glut_windowName, NULL,
  138.             __glut_window.width, __glut_window.height,
  139.             FDI_BORDER|FDI_TITLE|FDI_CONTENT|FDI_DRAG|FDI_FILLED|FDI_CLOSE);
  140.         ave_avo_addlink((ave_avo_t *) __glut_window.win, (ave_evt_t *) __glut_ave.app, CH_DIALOG_ACTION, EV_QUIT);
  141.     }
  142.     ave_app_addavo(__glut_ave.app, NULL, (ave_avo_t *) __glut_window.win, 0);
  143.     ave_avo_setpos((ave_avo_t *) __glut_window.win, __glut_window.x, __glut_window.y, 0);
  144.     ave_avo_settoken((ave_avo_t *) __glut_window.win, BFAVO_KEYTOKEN);
  145.     iglMakeCurrent(__glut_window.win, __glut_ctx);
  146.     __glut_window.width = ave_avo_getsize((ave_avo_t *) __glut_window.win).width;
  147.     __glut_window.height = ave_avo_getsize((ave_avo_t *) __glut_window.win).height;
  148.     __glut_windowCreated = GL_TRUE;
  149. }
  150.  
  151.  
  152. GLboolean __windowResized() {
  153.     return (ave_avo_getsize((ave_avo_t *) __glut_window.win).width    != __glut_window.width
  154.         || ave_avo_getsize((ave_avo_t *) __glut_window.win).height    != __glut_window.height);
  155. }
  156.  
  157.  
  158.  
  159. //////////// GLUT API Functions
  160.  
  161.  
  162. void glutInit(int *argcp, char **argv) {
  163.     strcpy(__glut_ave.execname, argv[0]);
  164.     if (__glut_ctx != NULL) {
  165.         __glutWarning("glutInit being called a second time.\n");
  166.         return;
  167.     }
  168.     __glut_initTime = microtime(NULL);
  169.     __glut_ctx = iglCreateContext();
  170.     kn_dev_lookup("/device/ave", (ELATE_OO_DATA **) &__glut_ave.ave, &__glut_ave.appname);
  171.     __glut_ave.app = ave_dev_open(__glut_ave.ave, (ELATE_OO_DATA *) __glut_ave.appname, 0, 0);
  172.     __glut_ave.tkit = ave_dev_opentoolkit(__glut_ave.ave, __glut_ave.app);
  173. }
  174.  
  175.  
  176. void glutInitWindowPosition(int x, int y) {
  177.     __glut_window.x = __glut_initX = x;
  178.     __glut_window.y = __glut_initY = y;
  179. }
  180.  
  181.  
  182. void glutInitWindowSize(int width, int height) {
  183.     __glut_window.width = __glut_initWidth = width;
  184.     __glut_window.height = __glut_initHeight = height;
  185. }
  186.  
  187.  
  188. int glutCreateWindow(char *name) {
  189.     __glut_windowName = name;
  190.     __glut_window.redisplay = GL_TRUE;
  191.     __glut_window.reshape = GL_TRUE;
  192.     __glut_window.reposition = GL_FALSE;
  193.     return __glut_numWindows++;
  194. }
  195.  
  196.  
  197. void glutSwapBuffers() {}
  198.  
  199.  
  200. void glutFullScreen(void) {
  201.     __glut_fullScreen = GL_TRUE;
  202.     __setupWindow();
  203. }
  204.  
  205.  
  206. void glutSetWindow(int win) {
  207.     __glut_currWindow = win;
  208. }
  209.  
  210.  
  211. int glutGetWindow(void) {
  212.     return __glut_currWindow;
  213. }
  214.  
  215.  
  216. void glutDestroyWindow(int win) {
  217.     iglDestroyContext(__glut_ctx);
  218.     ave_app_closeall(__glut_ave.app);
  219.     ave_dev_closetoolkit(__glut_ave.ave, __glut_ave.tkit);
  220.     ave_dev_close(__glut_ave.ave, __glut_ave.app);
  221.     __glut_numWindows--;
  222. }
  223.  
  224.  
  225.  
  226. void glutMainLoop(void) {
  227.     ave_event_t ave_event;
  228.     ave_message_t *msg;
  229.     ave_avo_pos_t windowPos;
  230.     
  231.     if (!__glut_windowCreated) {
  232.         __setupWindow();
  233.     }
  234.     do {
  235.         ave_event = ave_app_getevent(__glut_ave.app, 0);
  236.         msg = ave_event.msg;
  237.         if (ave_event.target != NULL) {
  238.             ave_evt_event(ave_event.target, ave_event.msg, ave_event.type);
  239.             
  240.             // ************** Handle mouse Events
  241.             if (__isMouseEvent(msg->EVD_TYPE)) {
  242.                 __glut_mouseX = msg->EVD_RX;
  243.                 __glut_mouseY = msg->EVD_RY;            
  244.                 if (msg->EVD_TYPE == EV_BUTTONDOWN || msg->EVD_TYPE == EV_BUTTONUP) {
  245.                     if (msg->EVD_TYPE == EV_BUTTONDOWN) {
  246.                         ave_avo_settoken((ave_avo_t *) __glut_window.win, BFAVO_KEYTOKEN);
  247.                         ave_avo_tofront((ave_avo_t *) __glut_window.win);
  248.                         __glut_currMBDown = __getMB(msg->EVD_BUTTONS);
  249.                     }
  250.                     if (__glut_mouseFunc != NULL) {
  251.                         __glut_mouseFunc(__getMB(msg->EVD_BUTTONS), __getMBState(msg->EVD_TYPE),
  252.                             __glut_mouseX, __glut_mouseY);
  253.                     }
  254.                     if (msg->EVD_TYPE == EV_BUTTONUP) {
  255.                         __glut_currMBDown = -1;
  256.                     }
  257.                 }
  258.                 if (msg->EVD_TYPE == EV_TRACKING) {
  259.                     if (__glut_currMBDown == -1 && __glut_passiveMotionFunc != NULL) {
  260.                         __glut_passiveMotionFunc(__glut_mouseX, __glut_mouseY);
  261.                     }
  262.                     if (__glut_currMBDown != -1 && __glut_motionFunc != NULL) {
  263.                         __glut_motionFunc(__glut_mouseX, __glut_mouseY);
  264.                     }
  265.                 }
  266.                 if (msg->EVD_TYPE == EV_ENTER || msg->EVD_TYPE == EV_LEAVE) {
  267.                     if (__glut_entryFunc != NULL) {
  268.                         __glut_entryFunc(__getMEntry(msg->EVD_TYPE));
  269.                     }
  270.                 }
  271.             }
  272.             
  273.             // ************** Handle keyboard events
  274.             if (__isKeyEvent(msg->EVD_TYPE)) {
  275.                 if (msg->EVD_TYPE == EV_KEYDOWN && __glut_keyboardFunc != NULL) {
  276.                     __glut_keyboardFunc(msg->EVD_KEY, __glut_mouseX, __glut_mouseY);
  277.                 }
  278.                 if (msg->EVD_TYPE == EV_KEYUP && __glut_keyboardUpFunc != NULL) {
  279.                     __glut_keyboardUpFunc(msg->EVD_KEY, __glut_mouseX, __glut_mouseY);
  280.                 }
  281.             }    
  282.         }
  283.         
  284.         ave_dev_freeevent((ave_dev_t *) __glut_ave.ave, msg);
  285.         
  286.         // ************* Handle callbacks
  287.         windowPos = ave_avo_getpos((ave_avo_t *) __glut_window.win);    
  288.         __glut_window.x = windowPos.x;
  289.         __glut_window.y = windowPos.y;
  290.         if (__glut_window.reposition) {
  291.             ave_avo_setpos((ave_avo_t *) __glut_window.win, __glut_window.x, __glut_window.y, 0);
  292.             __glut_window.reposition = GL_TRUE;
  293.         }
  294.         if (__glut_window.redisplay) {
  295.             __glut_displayFunc();        
  296.             ave_avo_update((ave_avo_t *) __glut_window.win);
  297.             __glut_window.redisplay = GL_FALSE;
  298.         }
  299.         if ((__glut_window.reshape || __windowResized()) && __glut_reshapeFunc != NULL) {
  300.             if (__windowResized() && !__glut_window.reshape) {
  301.                 __glut_window.width = ave_avo_getsize((ave_avo_t *) __glut_window.win).width;
  302.                 __glut_window.height = ave_avo_getsize((ave_avo_t *) __glut_window.win).height;
  303.             }
  304.             ave_avo_change((ave_avo_t *) __glut_window.win, __glut_window.x, __glut_window.y,
  305.                 __glut_window.width, __glut_window.height, CM_ADD);
  306.             __glut_reshapeFunc(__glut_window.width, __glut_window.height);
  307.             iglResizeContext(__glut_ctx, __glut_window.width, __glut_window.height, __glut_window.win);
  308.             __glut_window.reshape = GL_FALSE;
  309.         }
  310.         if (__glut_idleFunc != NULL) {
  311.             __glut_idleFunc();
  312.         }
  313.     } while (ave_event.type != EV_QUIT);
  314.     __shutdownGLUT();
  315. }
  316.  
  317.  
  318.  
  319. void glutPostRedisplay(void) {
  320.     __glut_window.redisplay = GL_TRUE;
  321. }
  322.  
  323.  
  324. void glutDisplayFunc(void (*func)(void)) {
  325.     __glut_displayFunc = func;
  326. }
  327.  
  328.  
  329. void glutReshapeFunc(void (*func)(int width, int height)) {
  330.     __glut_reshapeFunc = func;
  331. }
  332.  
  333.  
  334. void glutIdleFunc(void (*func)(void)) {
  335.     __glut_idleFunc = func;
  336. }
  337.  
  338.  
  339.  
  340. void glutKeyboardFunc(void (*func)(unsigned char key, int x, int y)) {
  341.     __glut_keyboardFunc = func;
  342. }
  343.  
  344.  
  345. void glutKeyboardUpFunc(void (*func)(unsigned char key, int x, int y)) {
  346.     __glut_keyboardUpFunc = func;
  347. }
  348.  
  349.  
  350. void glutMouseFunc(void (*func)(int button, int state, int x, int y)) {
  351.     __glut_mouseFunc = func;
  352. }
  353.  
  354.  
  355. void glutMotionFunc(void (*func)(int x, int y)) {
  356.     __glut_motionFunc = func;
  357. }
  358.  
  359.  
  360. void glutPassiveMotionFunc(void (*func)(int x, int Y)) {
  361.     __glut_passiveMotionFunc = func;
  362. }
  363.  
  364.  
  365. void glutEntryFunc(void (*func)(int state)) {
  366.     __glut_entryFunc = func;
  367. }
  368.  
  369.  
  370. void glutShowWindow(void) {
  371.     ave_avo_show((ave_avo_t *) __glut_window.win);
  372. }
  373.  
  374.  
  375. void glutHideWindow(void) {
  376.     ave_avo_hide((ave_avo_t *) __glut_window.win);
  377. }
  378.  
  379.  
  380. void glutPositionWindow(int x, int y) {
  381.     __glut_window.x = x;
  382.     __glut_window.y = y;
  383.     __glut_window.reposition = GL_TRUE;
  384. }
  385.  
  386.  
  387. void glutReshapeWindow(int width, int height) {
  388.     __glut_window.width = width;
  389.     __glut_window.height = height;
  390.     __glut_window.reshape = GL_TRUE;
  391. }
  392.  
  393.  
  394. int glutGet(GLenum state) {
  395.     __glut_screen = ave_avo_getscreen((ave_avo_t *) __glut_ave.ave);
  396.     switch (state) {
  397.     case GLUT_WINDOW_X :
  398.         return __glut_window.x;
  399.     case GLUT_WINDOW_Y :
  400.         return __glut_window.y;
  401.     case GLUT_WINDOW_WIDTH :
  402.         return __glut_window.width;
  403.     case GLUT_WINDOW_HEIGHT :
  404.         return __glut_window.height;
  405.     case GLUT_WINDOW_DEPTH_SIZE :
  406.         return 16;
  407.     case GLUT_WINDOW_PARENT :
  408.         return 0;
  409.     case GLUT_WINDOW_NUM_CHILDREN :
  410.         return 0;
  411.     case GLUT_SCREEN_WIDTH :
  412.         return __glut_screen.width;
  413.     case GLUT_SCREEN_HEIGHT :
  414.         return __glut_screen.height;
  415.     case GLUT_SCREEN_WIDTH_MM :
  416.         return 0;
  417.     case GLUT_SCREEN_HEIGHT_MM :
  418.         return 0;
  419.     case GLUT_INIT_WINDOW_X :
  420.         return __glut_initX;
  421.     case GLUT_INIT_WINDOW_Y :
  422.         return __glut_initY;
  423.     case GLUT_INIT_WINDOW_WIDTH :
  424.         return __glut_initWidth;
  425.     case GLUT_INIT_WINDOW_HEIGHT :
  426.         return __glut_initHeight;
  427.     case GLUT_ELAPSED_TIME :
  428.         return (int) ((microtime(NULL) - __glut_initTime)/1000);
  429.     }
  430.     return -1;
  431. }
  432.  
  433.  
  434. ///// Not implemented
  435. void glutInitDisplayMode(unsigned int mode) {}
  436.